Skip to content

feat: add reusable brutalist loader system with global switch logic#72

Merged
kunalverma2512 merged 2 commits into
kunalverma2512:mainfrom
Ushnika09:feat/global-loading-ui
May 17, 2026
Merged

feat: add reusable brutalist loader system with global switch logic#72
kunalverma2512 merged 2 commits into
kunalverma2512:mainfrom
Ushnika09:feat/global-loading-ui

Conversation

@Ushnika09
Copy link
Copy Markdown
Contributor

@Ushnika09 Ushnika09 commented May 17, 2026

Description

Implemented a reusable brutalist-style global loading system with centralized loader switching support.

Added two separate loader variants:

  • LoaderPrimary
  • LoaderAlt

A centralized LoaderSwitcher component was introduced to allow easy global switching between loaders using a simple boolean-based configuration without modifying existing components.

The loader is integrated inside DashboardPage.jsx and shared route loading flows for demonstration/testing purposes.

Related Issue

Fixes #10

Changes Made

  • Added reusable LoaderPrimary component
  • Added reusable LoaderAlt component
  • Added centralized LoaderSwitcher logic
  • Implemented boolean/config-based global loader switching
  • Updated shared loading usage to use LoaderSwitcher
  • Maintained brutalist UI guidelines and modular structure
  • Preserved both loader implementations with clean comments/readability

Loom Demo

https://www.loom.com/share/ac82ebe98747444fba51248c8f6f8ab5

Summary by CodeRabbit

  • New Features

    • Two distinct animated loader designs selectable at runtime for loading states.
  • Style

    • Redesigned accessible spinners with layered/alternating animations, staggered effects, and improved visual polish.
  • Refactor

    • Centralized loader selection used consistently across public, protected, and dashboard pages; legacy loader removed.

Review Change Stack

@github-actions
Copy link
Copy Markdown

🚀 PR Received Successfully

Hello @Ushnika09,

Thank you for taking the initiative to contribute to this project.

Please ensure that your PR follows all project guidelines properly before requesting review.

⚠️ Important Instructions

  • Maintain proper code quality and structure
  • Do not make unnecessary changes/files
  • Ensure responsiveness across devices
  • Follow existing project conventions strictly
  • Attach screenshots/videos for UI-related changes
  • Resolve merge conflicts before requesting review
  • Avoid AI-generated low quality PRs or copied implementations

📌 Mandatory for GSSoC'26 Participants

Joining the community group and announcement channel is compulsory for all contributors participating through GSSoC'26.

Failure to follow contribution guidelines may lead to PR rejection.

We appreciate your effort and wish you a great open-source journey ahead. ✨

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8731de4-2181-440b-a58d-f5f92eb3ce90

📥 Commits

Reviewing files that changed from the base of the PR and between 4879f17 and 4df82cd.

📒 Files selected for processing (7)
  • frontend/src/components/shared/Loader.jsx
  • frontend/src/components/shared/ProtectedRoute.jsx
  • frontend/src/components/shared/PublicRoute.jsx
  • frontend/src/components/shared/loaders/LoaderAlt.jsx
  • frontend/src/components/shared/loaders/LoaderPrimary.jsx
  • frontend/src/components/shared/loaders/LoaderSwitcher.jsx
  • frontend/src/pages/DashboardPage.jsx
💤 Files with no reviewable changes (1)
  • frontend/src/components/shared/Loader.jsx

📝 Walkthrough

Walkthrough

Replaces the removed Loader with two new loader components (LoaderPrimary, LoaderAlt), adds LoaderSwitcher to choose between them, and updates ProtectedRoute, PublicRoute, and DashboardPage to render LoaderSwitcher while auth is loading.

Changes

Loader Component Redesign and Migration

Layer / File(s) Summary
Primary multi-square loader animation
frontend/src/components/shared/loaders/LoaderPrimary.jsx
Defines a Spinner default export that renders a centered multi-layer animated spinner with nested squares and inline CSS keyframe animations (rotate, three scale variants, core pulse).
Alternative grid-based loader animation
frontend/src/components/shared/loaders/LoaderAlt.jsx
Adds a Spinner default export that renders four staggered grid tiles with an inline @keyframes grid animation and per-tile animationDelay.
Loader switcher coordination and consumer migration
frontend/src/components/shared/loaders/LoaderSwitcher.jsx, frontend/src/components/shared/ProtectedRoute.jsx, frontend/src/components/shared/PublicRoute.jsx, frontend/src/pages/DashboardPage.jsx
Adds LoaderSwitcher (module-level USE_ALT_LOADER flag) that returns LoaderAlt or LoaderPrimary. Updates ProtectedRoute, PublicRoute, and DashboardPage to import and render LoaderSwitcher during auth.loading. The previous frontend/src/components/shared/Loader.jsx default export was removed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I nibble code and spin a square,
Tiles flicker, rotate — a brutalist flair.
Switcher set, the loaders sing,
A tiny rabbit cheers the loading spring!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing a reusable brutalist loader system with centralized switching logic via a boolean configuration.
Linked Issues check ✅ Passed All requirements from issue #10 are met: a reusable Loader component (LoaderSwitcher) is created, geometric brutalist styling is implemented in LoaderPrimary and LoaderAlt, and it is integrated into DashboardPage for demonstration.
Out of Scope Changes check ✅ Passed All changes align with issue #10 objectives. The removal of the old Loader, creation of new loader variants, and integration into route components are all within scope for establishing the new loader system.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
frontend/src/components/shared/loaders/LoaderSwitcher.jsx (1)

6-6: ⚡ Quick win

Consider making the loader switch configurable.

The boolean flag is hard-coded, requiring a code change and redeployment to switch loaders globally. For easier testing and configuration across environments, consider using an environment variable or accepting a prop.

🔧 Proposed enhancement with environment variable
 // Centralized loader switching logic
-// Change this boolean to switch loaders globally
-const USE_ALT_LOADER = false; // Set to true to use the alternative loader
+// Set VITE_USE_ALT_LOADER=true in .env to switch loaders globally
+const USE_ALT_LOADER = import.meta.env.VITE_USE_ALT_LOADER === 'true';

Then you can toggle loaders in .env without code changes:

# .env
VITE_USE_ALT_LOADER=true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/shared/loaders/LoaderSwitcher.jsx` at line 6, Replace
the hard-coded constant USE_ALT_LOADER with a configurable source: read from an
environment variable (e.g., import.meta.env.VITE_USE_ALT_LOADER) and/or accept a
prop on the LoaderSwitcher component so callers can override it; update where
USE_ALT_LOADER is referenced in LoaderSwitcher.jsx to use the env value (coerced
to boolean) with the prop taking precedence, and document the new
VITE_USE_ALT_LOADER env var behavior.
frontend/src/components/shared/loaders/LoaderAlt.jsx (1)

1-1: ⚡ Quick win

Align component name with filename.

The internal component is named Spinner but the file is LoaderAlt.jsx. This inconsistency can confuse developers inspecting the component tree or debugging.

📝 Proposed fix
-const Spinner = () => {
+const LoaderAlt = () => {
   return (
-export default Spinner;
+export default LoaderAlt;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/shared/loaders/LoaderAlt.jsx` at line 1, The
component name inside the file is inconsistent: the function is declared as
Spinner but the file is LoaderAlt.jsx; rename the component to match the file
(e.g., change the function/component declaration from Spinner to LoaderAlt) and
update any default export or referenced name (component declaration and export)
so the component tree and debugging show LoaderAlt consistently.
frontend/src/components/shared/loaders/LoaderPrimary.jsx (1)

1-1: ⚡ Quick win

Align component name with filename.

The internal component is named Spinner but the file is LoaderPrimary.jsx. This inconsistency can confuse developers inspecting the component tree or debugging.

📝 Proposed fix
-const Spinner = () => {
+const LoaderPrimary = () => {
   return (
-export default Spinner;
+export default LoaderPrimary;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/shared/loaders/LoaderPrimary.jsx` at line 1, The
component defined as Spinner inside LoaderPrimary.jsx should be renamed to match
the filename: update the component declaration and any export to use
LoaderPrimary (and set LoaderPrimary.displayName = 'LoaderPrimary' if needed) so
the component tree and debugging reflect the correct name; also update any local
references or imports that use Spinner to use LoaderPrimary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/components/shared/loaders/LoaderAlt.jsx`:
- Around line 1-38: The Spinner component currently has no accessible text or
ARIA attributes; update the top-level container in the Spinner function to
expose loading state to assistive tech by adding role="status" and
aria-live="polite" (or aria-busy="true") and include a visually-hidden
descriptive element (e.g., a <span className="sr-only">Loading…</span>) inside
the container so screen readers announce the loader; ensure the project has a
.sr-only utility in global CSS or use inline styles for visually-hidden behavior
and keep the existing visual markup/animations (the change targets the Spinner
component's root div and its children).

In `@frontend/src/components/shared/loaders/LoaderPrimary.jsx`:
- Around line 1-104: The Spinner component currently renders only visual
elements (Spinner, class names animate-*) and lacks any accessible text or ARIA
attributes; update Spinner to include an offscreen screen-reader message (e.g.,
a span with visually-hidden/sr-only text like "Loading…" placed inside the root
div) and add role="status" and aria-live="polite" to the same container so
assistive tech announces the loading state; if .sr-only (or visually-hidden) is
not present in global CSS, add the provided sr-only utility rules to your global
stylesheet.

In `@frontend/src/pages/DashboardPage.jsx`:
- Line 14: Remove the unused debug constant by deleting the declaration "const
load = true" in the DashboardPage.jsx component (the unused symbol is "load");
if it was intended for a feature, either wire it into the component state/logic
(e.g., useState or props) and use it where appropriate, otherwise simply remove
the line to eliminate the dead variable.

---

Nitpick comments:
In `@frontend/src/components/shared/loaders/LoaderAlt.jsx`:
- Line 1: The component name inside the file is inconsistent: the function is
declared as Spinner but the file is LoaderAlt.jsx; rename the component to match
the file (e.g., change the function/component declaration from Spinner to
LoaderAlt) and update any default export or referenced name (component
declaration and export) so the component tree and debugging show LoaderAlt
consistently.

In `@frontend/src/components/shared/loaders/LoaderPrimary.jsx`:
- Line 1: The component defined as Spinner inside LoaderPrimary.jsx should be
renamed to match the filename: update the component declaration and any export
to use LoaderPrimary (and set LoaderPrimary.displayName = 'LoaderPrimary' if
needed) so the component tree and debugging reflect the correct name; also
update any local references or imports that use Spinner to use LoaderPrimary.

In `@frontend/src/components/shared/loaders/LoaderSwitcher.jsx`:
- Line 6: Replace the hard-coded constant USE_ALT_LOADER with a configurable
source: read from an environment variable (e.g.,
import.meta.env.VITE_USE_ALT_LOADER) and/or accept a prop on the LoaderSwitcher
component so callers can override it; update where USE_ALT_LOADER is referenced
in LoaderSwitcher.jsx to use the env value (coerced to boolean) with the prop
taking precedence, and document the new VITE_USE_ALT_LOADER env var behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 02e5a91a-7c1b-40bd-88d6-0602012d183a

📥 Commits

Reviewing files that changed from the base of the PR and between 4879f17 and c4fa1d6.

📒 Files selected for processing (7)
  • frontend/src/components/shared/Loader.jsx
  • frontend/src/components/shared/ProtectedRoute.jsx
  • frontend/src/components/shared/PublicRoute.jsx
  • frontend/src/components/shared/loaders/LoaderAlt.jsx
  • frontend/src/components/shared/loaders/LoaderPrimary.jsx
  • frontend/src/components/shared/loaders/LoaderSwitcher.jsx
  • frontend/src/pages/DashboardPage.jsx
💤 Files with no reviewable changes (1)
  • frontend/src/components/shared/Loader.jsx

Comment thread frontend/src/components/shared/loaders/LoaderAlt.jsx
Comment thread frontend/src/components/shared/loaders/LoaderPrimary.jsx
Comment thread frontend/src/pages/DashboardPage.jsx Outdated
@Ushnika09
Copy link
Copy Markdown
Contributor Author

I agree with CodeRabbit’s suggestions regarding removing the temporary debugging logic and adding ARIA accessibility support for screen readers — both improve overall UX and accessibility

The suggested changes have now been implemented.

Regarding moving the loader switch boolean into environment variables/config, I don’t think it is necessary here since it is not a sensitive value and the current centralized switching logic already keeps the implementation clean and maintainable.

@kunalverma2512
Copy link
Copy Markdown
Owner

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

✅ Actions performed

Full review triggered.

@kunalverma2512
Copy link
Copy Markdown
Owner

Excellent work on this PR.

Clean architecture, strong implementation, proper reasoning, and good handling of review feedback. The centralized loader switching system was implemented professionally and maintains good scalability.

Moving this to merge now.

Thanks, @Ushnika09 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Global Loading UI/Spinner

2 participants